<?php
require_once('wpfunctions.php');
require_once('liturgyfunctions.php');
// KEYS that get removed from engraving/verse section AND put into score master file
$engravingScoreKeys = array(
  'genrenumber',
  'engravinglabel',
  'spaceabovechant',
  'spacebelowchant',
  'overridetextleft',
  'overridetextright',
  'genrenumberleftright',
  'siglia'
);
$verseScoreKeys = array(
  'pagebreakbeforeverse'
);
// KEYS that get saved in section files
$sectionKeys = array_flip(array(
    'engraving',
    'verses',
    'addtoengraving',
    'psalmtone',
    'harmonizedpsalmtone',
    'sectionID',
    'sectionType',
    'verselabel',
    'psalmtitle',
    'versesource',
    'versefile',
    'psalmverse',
    'glorybe',
    'spacing',
    'psalmtone',
    'debug',
    'removetranslation',
    'markverses',
    'notateverses',
    'markpenultimateaccent',
    'allowpagebreaksmidverse'
  ));
// KEYS that get REMOVED from master file
$sectionKeysNoID = array_flip(array(
    'engraving',
    'verses',
    'siglia',
    'addtoengraving',
    'psalmtone',
    'harmonizedpsalmtone',
    'spacebelowchant',
    'spaceabovechant',
    'verselabel',
    'psalmtitle',
    'versesource',
    'versefile',
    'psalmverse',
    'glorybe',
    'spacing',
    'psalmtone',
    'footertext',
    'removetranslation',
    'markverses',
    'notateverses',
    'markpenultimateaccent',
    'allowpagebreaksmidverse',
    'engravings'
  ));
$regBold = '/\|+(\\S(?:.*?(?:([a-z])|\\S))?)\|+/i';
$regItalic = '/_+(\\S(?:.*?(?:([a-z])|\\S))?)_+/i';
function escapeTeX($text) {
  return preg_replace('/(?<!\\\\)&/', '\&', $text);
}
function ignoreBoldItalics($text) {
  global $regBold,$regItalic;
  return preg_replace('/[_|]/','', $text);
}
function reverseItalics($text) {
  return preg_replace('/__/','', "_{$text}_");
}
function applyTexBoldItalics($text) {
  global $regBold,$regItalic;
  return preg_replace('/(\\\\\\?{\\S})(\\\\text(?:bf|it){)/','$2$1',
            preg_replace('/\\\\\\?{[a-z]?}([^a-z]|$)/i','$1',
                preg_replace($regBold, '\\textbf{$1}\?{$2}',
                    preg_replace($regItalic, '\\textit{$1}\?{$2}', $text))));
}
function applyEmph($text) {
  global $regBold,$regItalic;
  //if((strlen($text) - 2) == strlen(str_replace('_','',$text)) &&
  //  $text[0] == '_' && $text[strlen($text)-1]=='_') {
  //  return str_replace('_','',$text);
  //}
  return preg_replace('/(\\\\\\?{\\S})(\\\\emph{)/','$2$1',
            preg_replace('/\\\\\\?{[a-z]?}([^a-z])/i','$1',
                preg_replace($regItalic.'s', '\\emph{$1}\?{$2}', $text)));
}

function normalizeFilename($title) {
  $fname = normalizer_normalize($title,Normalizer::FORM_KD);
  $fname = preg_replace('/\p{Mn}/u', '', $fname);
  $fname = preg_replace('/\'|\W+$/','',$fname);
  $fname = preg_replace('/\W+/','-',$fname);
  return $fname;
}
function remove_scorekeys($engravingSection) {
  global $verseScoreKeys,$engravingScoreKeys;
  $result = $engravingSection;
  foreach($result as $i => $engr) {
    foreach($verseScoreKeys as $j => $key) {
      unset($result[$i][$key]);
    }
    foreach($engravingScoreKeys as $j => $key) {
      unset($result[$i][$key]);
    }
  }
  return $result;
}
function sectionsForEngraving($engraving,$type=''){
  if($type == 'text') {
    $sectionDir = 'text-sections/';
  } else if($type =='engraving-Modern') {
    $sectionDir = 'engraving-sections/modern/';
  } else {
    $sectionDir = 'engraving-sections/square/';
  }
  $engravingName = str_replace(array('\\',' '),'-', preg_replace('/\.(?:gabc|txt|json)$/','',$engraving));
  return ip_scandirs("$sectionDir/$engravingName");
}
function gabcHeader($gabc){
  $theader = substr($gabc,0,strpos($gabc,'%%'));
  $header = array();
  $pattern = '/(?:^|\\n)(%?[\w-_]+):\s*([^;\\r\\n]+)(?:;|$)/i';
  if(preg_match_all($pattern, $theader, $matches)>0){
    foreach($matches[1] as $key => $value){
      $header[$value] = $matches[2][$key];
    }
  }
  $header['original-length'] = strlen($theader) + 2;
  return $header;
}
function stripHeader($gabc) {
  $result = substr($gabc,strpos($gabc,'%%')+2);
  $result = preg_replace('/^\s+|\s+$/','',$result);
  return $result;
}
function getPsalmFromSection($section) {
  if($section['psalmverse']) {
    $psalm = $section['psalmverse'];
  } else if($section['psalmtitle']) {
    $psalm = @psalmRef($section['psalmtitle']);
    if(!$psalm) {
      $psalm = $section['psalmtitle'];
    }
  }
  return $psalm;
}
function saveSection($section,$newID=false){
  global $sectionKeys, $sectionKeysNoID;
  $regexAlleluiaGenre = '/(alleluia)|(verse before the gospel)/i';
  if($section['sectionType'] == 'text') {
    $sectionDir = 'text-sections/';
  } else if($section['sectionType'] == 'engraving-Modern') {
    $isModern = true;
    $isEngraving = true;
    $sectionDir = 'engraving-sections/modern/';
  } else {
    $isEngraving = true;
    $sectionDir = 'engraving-sections/square/';
  }
  if($section['directory']) {
    $directory = $section['directory'] . '/';
  } else {
    $directory = '';
  }
  $alleluia = false;
  $title = $section['_title'];
  $super = $section['_super'];
  $sub = $section['_sub'];
  if($isEngraving && preg_match($regexAlleluiaGenre,$section['genre'],$match)) {
    $alleluia = true;
    $overrideFilename = $section['overrideFilename'];
    if($overrideFilename) {
      $engravingName = 'gospel-verses/'.$overrideFilename;
    } else if($title) {
      //TODO: $super and $sub are not getting passed in right now.
      $engravingName = getShortName($title,$super,$sub);
      if(!$engravingName) {
        $engravingName = preg_replace('/\s+/','-',$title);
      }
      $engravingName = $engravingName . ($match[1]? '_alleluia' : '_vbg');
      
      if(!$isModern) {
        foreach($section['engraving'] as $i => $engrav) {
          if($engrav['main']) {
            $gabc = $engrav['engraving'];
            break;
          }
        }
        $header = gabcHeader($gabc);
        $annotation = trim($header['annotation']);
        if($annotation) {
          $engravingName = $engravingName . "_$annotation";
        }
      }
      $engravingName = 'gospel-verses/'.mb_strtolower($engravingName,'UTF-8');
    } else {
      $engravingName = $section['sectionID'];
    }
  } else if(!$section['engraving']) {
    return;
  }
  
  if(!$alleluia) {
    if($isEngraving) {
      if(count($section['engraving'])>1) {
        $engravingName = 'hybrid/';
      } else {
        $engravingName = '';
      }
      foreach($section['engraving'] as $i => $engrav) {
        if($engrav['main']) {
          $engravingName .= $directory . str_replace(array('\\',' '),'-', preg_replace('/\.(?:gabc|txt|json)$/','',$engrav['engraving']));
          break;
        }
      }
    } else {
      $engravingName = $directory . str_replace(array('\\',' '),'-', preg_replace('/\.(?:gabc|txt|json)$/','',$section['engraving']));
    }
  }
  $sectionID = $section['sectionID'];
  if($sectionID) {
    //if it isn't a section ID for the correct engraving, get rid of it.
    if(substr($sectionID, 0, strlen($engravingName)) !== $engravingName){
      $sectionID = false;
    }
  }
  if(!$sectionID){
    if(!$newID) {
      return '';
    }
    $userPrefix = '';
    if(!ip_isAdministrator()) {
      $userPrefix = ip_userid() . '-';
    }
    if($alleluia) {
      $section['sectionID'] = $sectionID = $engravingName;
    } else {
      if(!is_dir(ip_userDir("$sectionDir/$engravingName"))) {
        mkdir(ip_userDir("$sectionDir/$engravingName"),0777,true);
        $num = 0;
      } else {
        $num = 0;
        while(ip_firstFile("$sectionDir/$engravingName/$userPrefix$num.json")) {
          ++$num;
        }
      }
      $section['sectionID'] = $sectionID = "$engravingName/$userPrefix$num";
    }
  }
  $section = array_intersect_key($section,$sectionKeys);
  $handle = fopen(ip_createFile("$sectionDir/$sectionID.json"), 'w');
  if(!$handle){
    //header("Content-type: text/plain");
    //echo "Unable to create file ".ip_userDir("$sectionDir/$sectionID.json");
    return $sectionID;
  }
  fwrite($handle,json_encode($section));
  fclose($handle);
  return $sectionID;
}
function engravingGABC($filename){
  $gabc = file_get_contents(ip_firstFile("engravings/square/$filename"));
  return preg_replace('/^(﻿)?\s*|\s+$/','',$gabc);
}
function psalmGABC($toneName) {
  if(strpos($toneName,'/') === false) {
    $toneName = "psalm-tones/$toneName";
  }
  $gabc = file_get_contents(ip_firstFile("engravings/square/$toneName"));
  return $gabc;
}
function clefNumber($clef) {
  if(preg_match('/(cb?|f)([1-4])/',$clef,$matches)) {
    return $matches[2];
  }
  return '4';
}
function translateGABC($gabc,$clef) {
  $header = gabcHeader($gabc);
  $gabc = substr($gabc,$header['original-length']);
  $gabc = preg_replace('/^\s+|\s+$/','',$gabc);
  $originalClef = $header['%clef'];
  $offset = 0;
  if($originalClef) {
    $originalClef = clefNumber($originalClef);
    $clef = clefNumber($clef);
    $offset = 2 * ($clef - $originalClef);
  }
  if($offset == 0) {
    return $gabc;
  } else {
    return preg_replace_callback('/[A-Ma-m]/', 
      create_function(
        '$matches',
        'return chr(' . $offset . ' + ord($matches[0]));'
      ),
      $gabc);
  }
}
function infoForPsalmTone($toneName) {
  return psalmToneInfo(psalmGABC($toneName),$toneName);
}
function calculateClef($endPitch, $endHeight) {
  $endPitch = ord(strtolower($endPitch)) - ord('a');
  $endHeight = ord(strtolower($endHeight)) - ord('a');
  $cLoc = ($endHeight - $endPitch + 9) % 7;
  switch($cLoc) {
    case 7:
      return 'c3';
    case 5:
      return 'c2';
    case 4:
      return 'f3';
    case 2:
      return 'c4';
    default:
      //unknown clef, so just use c4.
      return 'c4';
  }
}
function psalmToneInfo($gabc,$name=false) {
  if($name) {
    if(preg_match('/\/\d+([a-g])/i',$name,$matches)) {
      $psalmEndTone = $matches[1];
    }
  }
  $result = Array();
  $gabc = stripHeader($gabc);
  preg_match_all('/([a-m]r)((?:[^a-mr\n:;,]+[a-mxy]+(?!r))+)/',$gabc,$matches, PREG_SET_ORDER);
  $gabcResult = Array();
  foreach($matches as $m) {
    $gTemp = $m[1];
    $result[] = preg_match_all('/[^a-mr\n]+([a-mxy]+)/',$m[2],$matchArray, PREG_SET_ORDER) - 1;
    foreach($matchArray as $mi) {
      $gTemp .= ' ' . $mi[1];
    }
    $tmp = $mi[1];
    $gTemp = substr($gTemp,0,strlen($gTemp)-strlen($tmp)) . "'$tmp ${tmp}r $tmp.";
    $gabcResult[] = $gTemp;
  }
  $result['gabc'] = $gabcResult;
  if($psalmEndTone) {
    $result['clef'] = calculateClef($psalmEndTone, $tmp);
  }
  return $result;
}
function gloryBe($toneInfo, $accents = false, $markSyllables = false) {
  return textRef('',file_get_contents(ip_masterDir('verses/glorybe.txt')),$toneInfo, false, $accents, false, $markSyllables);
}
function removeEscapedAcuteAccents($text){
  return preg_replace_callback('/\\\\(\')({([^}]+)}|\b\S)/', 
    create_function(
      '$matches',
      'return $matches[3]? $matches[3] : $matches[2];'
    ),
    $text);
}
function removeEscapedDiacritics($text){
  return preg_replace_callback('/\\\\([`\'^"H~ckl=b.druvt])({([^}]+)}|\b\S)/', 
    create_function(
      '$matches',
      'return $matches[3]? $matches[3] : $matches[2];'
    ),
    $text);
}
function psalmRef($title, $toneInfo = Array(0,0), $gloryBe = false, $source='Psalm', $edition='rgp', $markpenultimateaccent = true, $keepVerseNumbers = false, $markSyllables = false, $allowJson = false) {
  $result = Array();
  $offset = 0;
  if(substr($edition,0,1) == '~') {
    $psalmText = file_get_contents(ip_firstFile("verses/$edition"));
    $psalmJson = json_decode($psalmText,true);
    if($psalmJson && $psalmJson['text']) {
      $psalmText = $psalmJson['text'];
    }
    $result[] = textRef('', $psalmText, $toneInfo, $gloryBe, false, $keepVerseNumbers, $markSyllables);
  } else {
    while(preg_match('/([\w-]+\.?)\s*(\d+)(?:\s*\(\d+)?([^;]+)?(;|$)/',$title, $matches, PREG_OFFSET_CAPTURE, $offset)) {
      if(!$source){
        $source = $matches[1][0];
        if($source == 'Ps.') {
          $source = 'Psalm';
        }
        if(!is_dir(ip_masterDir("verses/$source"))) {
          $source = 'Psalm';
        }
      }
      if(!$edition){
        $edition = 'rgp';
      }
      $psalmNum = $matches[2][0];
      $i = $matches[3][1];
      $offset = $matches[4][1];
      if($i < 0) {
        $curtitle = '';
      } else {
        $curtitle = substr($title,$i,$offset-$i);
      }
      $psalmText = file_get_contents(ip_masterDir("verses/$source/$edition/$psalmNum.txt"));
      $result[] = textRef($curtitle, $psalmText, $toneInfo, $gloryBe, false, $keepVerseNumbers, $markSyllables);
    }
  }
  $result = implode("\n\n",$result);
  if(!$markpenultimateaccent) {
    $result = removeEscapedAcuteAccents($result);
  }
  if($psalmJson && $allowJson) {
    $psalmJson['text'] = $result;
    $result = json_encode($psalmJson);
  }
  return $result;
}
function textRef($title, $psalmText, $toneInfo, $gloryBe = false, $accents = false, $keepVerseNumbers = false, $markSyllables = false, $onlyFirstItalic = false) {
  $ms = $toneInfo[0];
  $ts = $toneInfo[1];
  if($accents == false) {
    $psalmText = preg_replace('/\\\\\'([aeiouy])/i','$1',$psalmText);
  }
  if(!$markSyllables && is_numeric($ms) && $ms > '0') {
    if($onlyFirstItalic) {
      $regexMediant   =   '/(?<=[^a-z](?=[a-z\\\\]))([ +-]?[^ +-]+?)((?:[ +-]?[^ +-]+?){'.($ms-1).'})(?=[^a-zA-Z]*\|[^|\n]+\|[^|*\n]*\*)/ui';
    } else {
      $regexMediant   =   '/(?<=[^a-z](?=[a-z\\\\]))((?:[ +-]?[^ +-]+?){'.$ms.'})(?=[^a-zA-Z]*\|[^|\n]+\|[^|*\n]*\*)/ui';
    }
  }
  if(!$markSyllables && is_numeric($ts) && $ts > '0') {
    if($onlyFirstItalic) {
      $regexTermination = '/(?<=[^a-z](?=[a-z\\\\]))((?:[ +-]?[^ +-]+?))((?:[ +-]?[^ +-]+?){'.($ts-1).'})(?=[^a-z]*\|[^|\n]+\|[^*]*(?:\n|$))/ui';
    } else {
      $regexTermination = '/(?<=[^a-z](?=[a-z\\\\]))((?:[ +-]?[^ +-]+?){'.$ts.'})(?=[^a-z]*\|[^|\n]+\|[^*]*(?:\n|$))/ui';
    }
    
  }
  //$matchCount = preg_match_all('/(,)|(\d+)([a-z]*)(?:-(\d+)([a-z]*))?/',$title,$matches, PREG_SET_ORDER);
  $matchCount = preg_match_all('/(,)|(\d+)((?:[a-z](?:\s+and\s+)?)*)(?:-(\d+)((?:[a-z](?:\s+and\s+)?)*))?/i',$title,$matches, PREG_SET_ORDER);
  $regexLetters = '/([a-z])(?:\s+and\s+)?/i';
  if($matchCount == 0) {
    $result = preg_replace('/(?:(?<=\n)|^\W*)(\d+)\s+/',$keepVerseNumbers?'[$1]':'',$psalmText);
    $result = preg_replace('/(?<=^|\n)\s*\n/',"\n",$result);
    $result = preg_replace('/(?:(?<=\n)|^\W*) \s*/','',$result);
    $result = preg_replace('/(\*\s*\n)(\S)/','$1  $2',$result);
  } else {
    $result = '';
  }
  foreach($matches as $m) {
    if($m[1] == ',') {
      $result .= "\n";
      continue;
    }
    $startNum = $m[2];
    $startLet = $m[3];
    $endNum = $m[4];
    $endLet = $m[5];
    $oneVerse = false;
    if($startLet && strlen($startLet)>0) {
      $matchCount = preg_match_all($regexLetters,$startLet,$tmpMatches);
      $startLet = $tmpMatches[1];
    } else {
      $startLet = false;
    }
    if($endLet && strlen($endLet)>0) {
      $matchCount = preg_match_all($regexLetters,$endLet,$tmpMatches);
      $endLet = $tmpMatches[1];
    } else {
      $endLet = false;
    }
    if($endNum=='') {
      $oneVerse = true;
      $endNum=$startNum;
      $endLet=$startLet;
    }
    $start = preg_match('/(?:\n|^)\W*('.$startNum.')\s*/',$psalmText,$startMatch, PREG_OFFSET_CAPTURE);
    if($start == 0) {
      $result .= "{Starting Verse $startNum not found}\n";
      continue;
    }
    $start = $startMatch[1][1];
    $lines = explode("\n",preg_replace('/(?<=^|\n)\s*?\n/','',substr($psalmText,$start)));
    $verse = '';
    if($startLet) {
      foreach($startLet as $let) {
        $versePart = ord($let) - ord('a');
        $verse .= $lines[$versePart] . "\n";
      }
      if(!$oneVerse) {
        while($versePart >= 0) {
          $start += 1 + strlen($lines[$versePart]);
          --$versePart;
        }
      }
    }
    /*
    if($startLet) {
      while($versePart > 0) {
        $count = preg_match('/\*\s*\n\S/',$psalmText,$startMatch, PREG_OFFSET_CAPTURE,$start);
        if($count == 0) {
          $result .= "{Error finding beginning of verse $startNum$startLet}";
        }
        $start = $startMatch[0][1];
        $count = preg_match('/[a-z]+.*\n/',$psalmText,$startMatch, PREG_OFFSET_CAPTURE,$start);
        if($count == 0) {
          $result .= "{Error in finding beginning of verse $startNum$startLet}";
          $result .= substr($psalmText,$start);
        }
        $start = $startMatch[0][1] + strlen($startMatch[0][0]);
        --$versePart;
      }
    }
    */
    if($oneVerse && $verse != '') {
      $verse = preg_replace('/(?<=^|\n)(?:(\d+)\s+|\s*?\n)/',$keepVerseNumbers?'[$1]':'',$verse);
      $verse = preg_replace('/(\*\s*\n)(\S)/','$1  $2',$verse);
      $result .= $verse;
      continue;
    }
    $end = preg_match('/(?:\n|^)\W*('.$endNum.')\s+/',$psalmText,$endMatch, PREG_OFFSET_CAPTURE);
    if($end == 0) {
      $result .= "{Ending Verse $endNum not found}\n";
      continue;
    }
    $extraVerse = '';
    if($endLet) {
      $end = $endMatch[1][1];
      $lines = explode("\n",preg_replace('/(?<=^|\n)\s*?\n/','',substr($psalmText,$end)));
      foreach($endLet as $let) {
        $versePart = ord($let) - ord('a');
        $extraVerse .= "\n" . $lines[$versePart];
      }
      $extraVerse .= "\n";
      $versePart = ord($endLet[0]) - ord('a') - 1;
      while($versePart >= 0) {
        $end += 1 + strlen($lines[$versePart]);
        --$versePart;
      }
    } else {
      $end = preg_match('/(?<=^|\n)\d+ |$/',$psalmText,$endMatch, PREG_OFFSET_CAPTURE, 1+$endMatch[1][1]);
      if($end == 0) {
        $result .= "{end of verse $endNum not found}\n";
        continue;
      }
      $end = $endMatch[0][1];
    }
    $verse .= substr($psalmText,$start,$end - $start) . $extraVerse;
    $verse = preg_replace('/(?<=^|\n)(?:(\d+)\s+|\s*?\n)/',$keepVerseNumbers?'[$1]':'',$verse);
    $verse = str_replace('[]','',$verse);
    $verse = preg_replace('/(\*\s*\n)(\S)/','$1  $2',$verse);
    $result .= $verse;
  }
  if($regexMediant) {
    $result = preg_replace($regexMediant,'_$1_$2',$result);
  }
  if($regexTermination) {
    $result = preg_replace($regexTermination,'_$1_$2',$result);
  }
  if($onlyFirstItalic) {
    $result = str_replace('|','',$result);
  }
  $result = str_replace('+',$markSyllables?'=':'',$result);
  $result = preg_replace('/\n+$/','',$result);
  if($gloryBe) {
    $result .= "\n\n" . gloryBe($toneInfo, $accents, $markSyllables);
  }
  return $result;
}
?>